package com.telenav.snowsweeper.controller;

import java.util.HashMap;
import java.util.Vector;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;

import com.telenav.snowsweeper.R;
import com.telenav.snowsweeper.data.Edge;
import com.telenav.snowsweeper.data.EdgeMap;
import com.telenav.snowsweeper.data.PassPoint;
import com.telenav.snowsweeper.net.ICallBack;
import com.telenav.snowsweeper.net.IRequest;
import com.telenav.snowsweeper.net.MapDataRequest;
import com.telenav.snowsweeper.net.PassPointRequest;
import com.telenav.snowsweeper.net.ThreadPool;
import com.telenav.snowsweeper.util.DataUtil;

public class GameLoader implements ICallBack {
	
	Activity context;
	GameController gameController;
	GameDataPackage dataPackage;
	private ProgressBar progress;
	
	
	public GameLoader(Activity context) {
		this.context = context;
	}
	
	public void loadGame(GameDataPackage dataPackage, GameController controller) {
		this.dataPackage = dataPackage;
		gameController = controller;

		ThreadPool.getInstance().addJob(new MapDataRequest(this, dataPackage.gameLevel));
		ThreadPool.getInstance().addJob(new PassPointRequest(this, dataPackage.gameLevel, dataPackage.currReqPPIndex));

		context.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				ViewGroup vg = (ViewGroup) inflater.inflate(R.layout.activity_loading, null);
				context.setContentView(vg);
				progress = (ProgressBar) vg.findViewById(R.id.progressBar);
				progress.setVisibility(View.VISIBLE);
			}
		});
	}
	
	@Override
	public boolean parseData(IRequest request, String response) {
		if (request instanceof MapDataRequest) {
			Vector<Edge> edges = DataUtil.parseMapData(response);
			if (edges != null) {
				dataPackage.mapData = new EdgeMap(edges);
			}
		}
		else if (request instanceof PassPointRequest) {
			PassPoint pp = DataUtil.parsePassPoint(response);
			if (pp != null) {
				pp.level = dataPackage.gameLevel;
				pp.index = ((PassPointRequest) request).getRequestPassPointIndex();
				dataPackage.totalPPCount = pp.count + 1; // pp count means: except the first
												// one, total pp number
				if (dataPackage.passPoints == null) {
					dataPackage.passPoints = new HashMap<Integer, PassPoint>();
				}
				dataPackage.passPoints.put(dataPackage.currReqPPIndex, pp);
				dataPackage.currReqPPIndex++;
			}
		}
		if (checkDataReady()) {
			context.runOnUiThread(new Runnable() {
				@Override
				public void run() {
					gameController.enterGame(context, R.id.mapcanvas, dataPackage.mapData, dataPackage.passPoints);
				}
			});
		}
		else {
			// only used for request index = 1 passpoint
			if (dataPackage.passPoints != null) {
				ThreadPool.getInstance().addJob(
						new PassPointRequest(this, dataPackage.gameLevel, dataPackage.currReqPPIndex));
			}
		}
		return true;
	}

	@Override
	public void failedRequest(IRequest quest) {
		final EdgeMap data = new EdgeMap(DataUtil.parseMapData(DataUtil.fakeMapData));
		context.runOnUiThread(new Runnable() {
			@Override
			public void run() {
				gameController.enterGame(context, R.id.mapcanvas, data, null);
			}
		});
	}
	
	private boolean checkDataReady() {
		// data ready condition: pass points's size is equal to passpoint's
		// count
		// if too slow, we could consider to optimize this one
		boolean ready = dataPackage.mapData != null && dataPackage.passPoints != null
				&& dataPackage.passPoints.size() >= dataPackage.totalPPCount;
		return ready;
	}
}